package com.example.interview.algorithm;

/**
 * 实现函数double Power(double base, int exponent)，求base的exponent次方。
 * 不得使用库函数，同时不需要考虑大数问题。
 * 
 * @Description: TODO
 * @author gaobing
 * @date 2018年10月8日 下午1:30:34
 *
 */
public class Test11DoublePower {

	/**
	 * 
	 * @param base
	 *            底数
	 * @param exponent
	 *            指数
	 * @return
	 */
	public static double power(double base, int exponent) {
		// 指数和底数不能同时为0
		if (base == 0 && exponent == 0) {
			throw new RuntimeException("invalid input.base and exponent both are zero");
		}
		// 指数为0返回1
		if (exponent == 0) {
			return 1;
		}
		// 求指数的绝对值
		long exp = exponent;
		if (exponent < 0) {
			exp = -exp;
		}
		// 求幂次方
		double result = powerWithUnsignedExponent(base, exp);

		// 指数是负数，求倒数
		if (exponent < 0) {
			result = 1 / result;
		}
		return result;
	}

	/**
	 * 求一个数的正整数次幂，不考虑溢出
	 * 
	 * @param base
	 * @param exp
	 * @return
	 */
	private static double powerWithUnsignedExponent(double base, long exponent) {
		// 如果指数是0 返回1
		if (exponent == 0) {
			return 1;
		}
		// 指数是1 返回底数
		if (exponent == 1) {
			return base;
		}
		// 递归求一半的值
		double result = powerWithUnsignedExponent(base, exponent >> 1);

		result *= result;
		// 求最终值，如果是奇数还要乘以一次底数
		if (exponent % 2 != 0) {
			result *= base;
		}
		return result;
	}

	public static void main(String[] args) {
		System.out.println(0.0000000000000000000000001111 == 0);
		System.out.println(0.0000000000000000000000000000 == 0);
		System.out.println(power(2, -4));
		System.out.println(power(2, 4));
		System.out.println(power(2, 0));
		System.out.println(power(0.00000000000000000000000000001, -1));
		System.out.println(power(0.00000000000000000000000000001, 1));
		System.out.println(power(0.00000000000000000000000000001, 0));
		//System.out.println(power(0.00000000000000000000000000000, 0));
		System.out.println(power(0, 2));
	}
}
